#ifndef PROBLEM_H
#define PROBLEM_H

#include "Coordinate.h"
//#include "mvf.h"

//abstract class
struct Function
{
    std::string name;
    int dim;
    bool isMinKnown;
    double min;
    bool isSameBoundryForAll;
    std::vector<double> bounds;
    std::vector<double> atPoint;
};

class Problem
{
public:
//static method called like: Problem::printListOfProblems(); can be call from any class does not matter that it is abstract
    static Problem * createProblem(int problemNumber=1);
    Problem();
    virtual ~Problem();
    void printProblem()const;
    void printCoordinates()const;
//put this initialization into onother method Coordinate cor4 soit goes long before program terminates; and
//then do setCoordinate(cor4) cor4 is not allocated dynamiclly so it goes when method finished
//create Coordinate object dinamiccly as passing to the method :setCoordinate(*(new Coordinate(-1,7)))
    void setCoordinate(Coordinate coor);
    void setCoordinate(double & lower, double & upper);
    //arrays are passed by default by reference, but not vectors
    //can't be return by reference couse computed value is going out of scope after this funcion
    //terminatesS, couse it is not created dynamicly within the method
    virtual double computeValue(std::vector<double> & populationMember)=0;
    virtual void setFunction(unsigned int number)=0;
    bool getMinimum()const
    {
        return minimum;
    }
    void setMinimum(bool min)
    {
        minimum=min;
    }
    unsigned int getDimention()const
    {
        return dimention;
    }
    void setDimention(unsigned int dim)
    {
        dimention=dim;
    }
    bool getKnownOptimum()const
    {
        return knownOptimum;
    }
    void setKnownOptimum(bool known)
    {
        knownOptimum=known;
    }

    double getBestKnownOptimum()const
    {
        return bestOptimum;
    }
    void setBestKnownOptimum(double best)
    {
        bestOptimum=best;
    }
    unsigned int getNumberOfProblems()const
    {
        return numberOfProblems;
    }
    void setNumberOfProblems(unsigned int val)
    {
        numberOfProblems=val;
    }
    std::vector<Coordinate> & getCoordinates()
    {
        return coordinates;
    }
    std::vector<Function> & getFun()
    {
        return  fun;
    }


private:
    Problem(const Problem& other);
    Problem& operator=(const Problem& other);


    std::vector<Coordinate> coordinates;
    bool minimum;
    int dimention;
    double bestOptimum;
    bool knownOptimum;
    unsigned int numberOfProblems;
public:
    std::vector<Function> fun;

};

#endif // PROBLEM_H
